#ifndef CORE_CACHE
#define CORE_CACHE

#include "typedef.hpp"
#include <array>

using CacheMessage = uint64_t;

struct CacheLine
{
	std::array<uint8_t, 64> data;
	MESIMETA meta = Invalid;
	uint8_t *operator()() { return data.data(); }
};
using CacheList = std::pair<uint32_t, CacheLine>;	   // tag,line
using Index = std::tuple<uint32_t, uint16_t, uint8_t>; // tag,index,load/store

class CacheBlock
{
private:
	std::list<CacheList> lines;
	std::unordered_map<uint32_t, std::list<CacheList>::iterator> idx;

public:
	int size;
	CacheBlock() = default;
	CacheBlock(int size) : size(size) {}
	~CacheBlock() = default;
	CacheLine &operator[](Index);
	void clear(uint16_t,uint8_t);
};

class Cache
{
private:
	std::map<uint16_t, CacheList> l1i;	// 1-way,index range:0~1023
	std::map<uint16_t, CacheBlock> l1d; // 4-way,index range:0~1023
	std::map<uint16_t, CacheBlock> l2;	// 2-way,index range:0~16383
	Atomic<CacheMessage> *cache_bus;
	// 块广播函数，由读写函数调用
	void broadcast(uint64_t addr)
	{
		cache_bus->w_lock();
		cache_bus->get() = addr;
		cache_bus->w_unlock();
	}
	void refresh() {}

public:
	Cache() = default;
	Cache(Atomic<CacheMessage> *bus) : cache_bus(bus) {}
	~Cache() = default;
	// 读写函数，由处理器直接调用
	void read(uint64_t, uint64_t *, uint8_t);
	void readIns(uint64_t, uint64_t *);
	void write(uint64_t, uint64_t *, uint8_t);
	void operator()(uint64_t, uint64_t *, uint8_t, uint8_t);
	void shutdown();
};

#endif